package com.ainge.easystudy.thread;

import java.util.concurrent.Semaphore;

/**
 * @author: Ainge
 * @Time: 2021/8/30 00:59
 */
public class SemaphoreTest {


    public static void main(String[] args) throws InterruptedException {
        LimitDbConnection<Double> limitDbConnection = new LimitDbConnection<>(2, Math::random);
        new Thread(()->{
            try {
                System.out.println( limitDbConnection.connectAndExecute());
            } catch (InterruptedException e) {
            }
        }).start();
        new Thread(()->{
            try {
                System.out.println( limitDbConnection.connectAndExecute());
            } catch (InterruptedException e) {
            }
        }).start();
        new Thread(()->{
            try {
                System.out.println( limitDbConnection.connectAndExecute());
            } catch (InterruptedException e) {
            }
        }).start();
        new Thread(()->{
            try {
                System.out.println( limitDbConnection.connectAndExecute());
            } catch (InterruptedException e) {
            }
        }).start();
        new Thread(()->{
            try {
                System.out.println( limitDbConnection.connectAndExecute());
            } catch (InterruptedException e) {
            }
        }).start();
        new Thread(()->{
            try {
                System.out.println( limitDbConnection.connectAndExecute());
            } catch (InterruptedException e) {
            }
        }).start();
        new Thread(()->{
            try {
                System.out.println( limitDbConnection.connectAndExecute());
            } catch (InterruptedException e) {
            }
        }).start();




    }

    interface Task<R>{

        /**
         * 执行任务并且返回R
         * @param
         * @return
         */
        R execute();

    }

    // 限制数据库连接数
    static class LimitDbConnection<R> implements Task<R>{

        private Semaphore semaphore;
        private Task<R> task;

        LimitDbConnection(int limit,Task<R> task){
            semaphore = new Semaphore(limit);
            this.task = task;
        }

        // 获取数据库连接并且执行业务
        public R connectAndExecute() throws InterruptedException {
            try {
                semaphore.acquire();
                // 模拟查询耗时
                System.out.println("进入----");
                Thread.sleep(1000);
                return execute();
            }catch (Exception e){
                System.out.println(e.getMessage());
                throw e;
            }finally {
                semaphore.release();
            }
        }


        @Override
        public R execute() {
            return task.execute();
        }
    }

}
